﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MIMSDomain.Concrete;
using MIMSDomain.Entities;
using MIMSDomain.Abstract;
using Moq;

namespace MIMSUnitTests.Domain
{
    [TestClass]
    public class EFOccupationRepositoryTests
    {
        public IRepository<Occupation> MockOccupationRepository;

        [TestInitialize]
        public void Initialize(){
            var _occupations = new List<Occupation>
            {
                new Occupation{ Id=1, Name="Junior Developer"},
                new Occupation{ Id=2, Name="Senior Developer"},
                new Occupation{ Id=3, Name="Solution Architect"},
                new Occupation{ Id=4, Name="Tailor"},
                new Occupation{ Id=5, Name="Policeman"},
                new Occupation{ Id=6, Name="Network Engineer"},
                new Occupation{ Id=7, Name="Mechanic"}
            };

            var target = new Mock<EFOccupationRepository>();
            target.Setup(p => p.All).Returns(_occupations.AsQueryable());
            target.Setup(p => p.GetById(It.IsAny<int>())).Returns((int i) => _occupations.Where(p => p.Id == i).Single());
            target.Setup(p => p.Save(It.IsAny<Occupation>())).Returns((Occupation objOccupation) =>
            {
                if(objOccupation.Id.Equals(default(int))){
                    objOccupation.Id = _occupations.Count() + 1;
                    _occupations.Add(objOccupation);

                }
                else{
                    var original = _occupations.Where(p => p.Id == objOccupation.Id).Single();
                    if (original == null)
                    {
                        return false;
                    }
                    original.Name = objOccupation.Name;
                }

                return true;
            });
            target.Setup(p => p.Delete(It.IsAny<Occupation>())).Returns((Occupation objOccupation) => {
                if (objOccupation != null)
                {
                    if (_occupations.Contains(objOccupation))
                    {
                        _occupations.Remove(objOccupation);
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
                return true;
            });

            MockOccupationRepository = target.Object;
        }
        
        [TestMethod]
        public void CanSaveOccupation()
        {
            //Arrange
            var count = MockOccupationRepository.All.Count();
            //Assert
            Assert.AreEqual(7, count); //Confirm blood group count before saving
            //Act
            var expected = MockOccupationRepository.Save(new Occupation { Name = "Project Manager" });

            //Assert
            count = MockOccupationRepository.All.Count();
            Assert.AreEqual(8, count); //Confirm blood group count after saving
        }

        [TestMethod]
        public void CanGetOccupationById()
        {
            //Act
            var expected = MockOccupationRepository.GetById(3);
            //Assert
            Assert.IsNotNull(expected);
            Assert.IsInstanceOfType(expected, typeof(Occupation));
            Assert.AreEqual(expected.Name, "Solution Architect");
        }

        [TestMethod]
        public void CanDeleteOccupation()
        {
            //Arrange
            var count = MockOccupationRepository.All.Count();
            Assert.AreEqual(7, count);
            var objOccupation = MockOccupationRepository.GetById(3);
            Assert.IsInstanceOfType(objOccupation, typeof(Occupation));
            //Act
            MockOccupationRepository.Delete(objOccupation);
            count = MockOccupationRepository.All.Count();
            //Assert
            Assert.AreEqual(6, count);
        }

        [TestMethod]
        public void CannotAddDuplicateOccupation()
        {
            throw new NotImplementedException();
        }

    }
}
